#include "..\include\CGameClass.h"

CGameClass::CGameClass(void)
{
	m_fMouseAngleYaw = m_fMouseAnglePitch = 0.0f;
	this->m_bRightButtonClick = false;
}

CGameClass::~CGameClass(void)
{
}

//=====================================================
// Function	:	GetInstance()
//
// Out		:	CGameClass& - Handle to our single game class instance
//
//	Purpose	:	To return a reference to our Game Class Instance
//=====================================================
CGameClass* CGameClass::GetInstance(void)
{
	static CGameClass Instance;
	return &Instance;
}

//=====================================================
// Function	:	Initialize()
//
// Out		:	bool - Did we Initialize successfully? If so return true.
//
//	Purpose	:	Contain all initialization for our game, D3D, sound, textures.. etc.
//=====================================================
bool CGameClass::Initialize(int nScreenWidth, int nScreenHeight, HWND hWnd)
{
	// Set up our screen scale value
	m_fScaleScreenX = (float)(nScreenWidth / 1280);
	m_fScaleScreenY = (float)(nScreenHeight / 1024);

	// Initalize DirectX
	this->m_pDirect3D = CD3DWrapper::GetInstance();
	if(!this->m_pDirect3D->InitializeD3D(hWnd, nScreenWidth, nScreenHeight, true))
		return false;

	// Set the projection matrix
	D3DXMATRIX proj;
	D3DXMatrixPerspectiveFovLH(&proj,
										    (float)D3DX_PI * 0.5f,
											(float)nScreenWidth / (float)nScreenHeight,
											1.0f,
											2000.0f);
	this->m_pDirect3D->GetDevice()->SetTransform(D3DTS_PROJECTION, &proj);

	// Attempt to create some lighting
	D3DLIGHT9 light;
	ZeroMemory(&light, sizeof(light));

	light.Type			= D3DLIGHT_DIRECTIONAL;
	light.Diffuse		= D3DXCOLOR(1.0f,  1.0f, 1.0f, 1.0f);
	light.Ambient		= D3DXCOLOR(1.0f,  1.0f, 1.0f, 1.0f) * 0.4f;
	light.Specular		= D3DXCOLOR(1.0f,  1.0f, 1.0f, 1.0f) * 0.3f;
	light.Direction    = D3DXVECTOR3(1.0f, 0.0f, 0.0f);

	this->m_pDirect3D->GetDevice()->SetLight(0, &light);
	this->m_pDirect3D->GetDevice()->LightEnable(0, true);	
	
	// Set our render states
	this->m_pDirect3D->GetDevice()->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
	this->m_pDirect3D->GetDevice()->SetRenderState(D3DRS_LIGHTING, true);
	this->m_pDirect3D->GetDevice()->SetRenderState(D3DRS_SPECULARENABLE, true);
	this->m_pDirect3D->GetDevice()->SetRenderState(D3DRS_ZENABLE, true);
	this->m_pDirect3D->GetDevice()->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
	this->m_pDirect3D->GetDevice()->SetRenderState(D3DRS_CLIPPING, true);
	this->m_pDirect3D->GetDevice()->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
	this->m_pDirect3D->GetDevice()->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
	this->m_pDirect3D->GetDevice()->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
 
	// Initialize our camera
	m_pCamera = new CCamera(CCamera::AIRCRAFT);
	m_pCamera->SetPosition(D3DXVECTOR3(0.0f, 0.0f, -5.0f));
	m_pCamera->Initialize(m_pDirect3D->GetDevice());

	// Create terrain
	m_pTerrain = new CTerrain(m_pDirect3D->GetDevice(), "textures/testing4.raw", 256, 256, 10, 1.0f);
	//m_pTerrain->LoadTexture("textures/grass.bmp");
	m_pTerrain->GenTexture(&D3DXVECTOR3(0.0f, 1.0f, 0.0f));

	// Set up the model manager
	m_pModelManager = CModelManager::GetInstance();
	m_pModelManager->Initialize(this->m_pDirect3D->GetDevice());
	nDrone = m_pModelManager->AddModel("EvilDrone.x");

	return true;
}

//=====================================================
// Function	:	Draw()
//
// Out		:	bool - Did we Draw successfully? If so return true.
//
//	Purpose	:	Display our game to the screen
//=====================================================
bool CGameClass::Draw(void)
{
	this->Update();

	if(this->m_pDirect3D->GetDevice())
	{
		D3DXVECTOR3 pos;
		m_pCamera->GetPos(&pos);

		float height = m_pTerrain->GetHeight(pos.x, pos.z);
		pos.y = height + 60.0f;

		m_pCamera->SetPosition(pos);

		// Update the view matrix representing the camera new pos/ orientation
		D3DXMATRIX V;
		m_pCamera->GetViewMatrix(&V);
		this->m_pDirect3D->GetDevice()->SetTransform(D3DTS_VIEW, &V);

		this->m_pDirect3D->Clear(35, 35, 95);
		this->m_pDirect3D->GetDevice()->BeginScene();

		// Draw the terrain
		D3DXMATRIX I;
		D3DXMatrixIdentity(&I);
		this->m_pTerrain->Draw(&I, false);


		// Draw the first model
		m_pModelManager->ScaleModel(nDrone, 100.0f, 100.0f, 100.0f);
		m_pModelManager->TranslateModel(nDrone, 0.0f, 350.0f, 350.0f);
		this->m_pModelManager->DrawAllModels();

		this->m_pDirect3D->GetDevice()->EndScene();
		this->m_pDirect3D->Present();
	}

	return true;
}

//=====================================================
// Function	:	Update()
//
// Out		:	bool - Did we update successfully? If so return true.
//
//	Purpose	:	Update Game logic, character positions, objects... etc.
//=====================================================
bool CGameClass::Update(void)
{

	if(GetAsyncKeyState('W'))
		m_pCamera->walk(0.1f);

	if(GetAsyncKeyState('S'))
		m_pCamera->walk(-0.1f);

	if(GetAsyncKeyState('A'))
		m_pCamera->yaw(-0.001f);

	if(GetAsyncKeyState('D'))
		m_pCamera->yaw(0.001f);

	if(GetAsyncKeyState(VK_UP))
		m_pCamera->fly(2.5f);

	if(GetAsyncKeyState(VK_DOWN))
		m_pCamera->fly(-2.5f);

	return true;
}

void CGameClass::OnRightMouseClick(float x, float y)
{
	m_bRightButtonClick = false;

	this->m_fRightClickx = x;// * this->m_fScaleScreenX;
	this->m_fRightClicky = y;// * this->m_fScaleScreenY;

	m_bRightButtonClick = true;
}

void CGameClass::OnMouseMove(float x, float y)
{
	float tempX = x;// * this->m_fScaleScreenX;
	float tempY = y;// * this->m_fScaleScreenY;

	if(m_bRightButtonClick)
	{
		m_fMouseAngleYaw = (tempX - m_fRightClickx) * 0.001f;
		m_fMouseAnglePitch = tempY - m_fRightClicky;
	}
	/*if(x > (m_fRightClickx + 20))
		m_fMouseAngleYaw = 0.05f;
	else if(x < (m_fRightClickx - 20))
		m_fMouseAngleYaw = -0.05f;
	else
		m_fMouseAngleYaw = 0.0f;*/

	/*if(y > (m_fRightClicky + 50))
		m_fMouseAnglePitch = 0.05f;
	else if(y < (m_fRightClicky - 50))
		m_fMouseAnglePitch = -0.05f;
	else
		m_fMouseAnglePitch = 0.0f;*/
	
	m_pCamera->yaw(m_fMouseAngleYaw);
	//m_pCamera->pitch(m_fMouseAnglePitch);
}


//=====================================================
// Function	:	CleanUp()
//
//	Purpose	:	Clean up all of our dynamic memory and COM objects
//=====================================================
void CGameClass::CleanUp(void)
{

}